Skip to content

Conversation

mediocregopher
Copy link
Collaborator

Closes #18517

This PR primarily targets the unwind_trie_state_range provider method, which is used by the engine API to unwind the db during reorgs.

This method was previously also potentially used by the unwind pipeline stage, but only in an else block which should never get hit anymore. This else block was replaced with an error.

unwind_trie_state_range was previously recomputing trie updates using a StateRoot calculation, but it is now able to skip that step and simply read trie updates from the trie changeset tables instead. To make applying these updates easier the write_trie_updates method is superceded by write_trie_updates_sorted.

@github-project-automation github-project-automation bot moved this to Backlog in Reth Tracker Oct 6, 2025
@github-actions github-actions bot added A-db Related to the database A-trie Related to Merkle Patricia Trie implementation C-enhancement New feature or request labels Oct 6, 2025
@mediocregopher mediocregopher force-pushed the mediocregopher/18517-trie-cs-unwind branch from bdaeb41 to 70d24d4 Compare October 6, 2025 16:25
@mediocregopher mediocregopher marked this pull request as ready for review October 6, 2025 16:33
Copy link
Member

@Rjected Rjected left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that this makes things simpler, I have a question and suggestion for a helper method but otherwise this looks good to me

Comment on lines 357 to 358
let trie_revert = self.trie_reverts(range.clone())?;
self.write_trie_updates_sorted(&trie_revert)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, i like that this is now just a call to a provider fn

Comment on lines 62 to 90
// Sanity check that we have static files available to unwind to the target block.
let highest_static_file_block =
provider_factory.static_file_provider().get_highest_static_files().max_block_num();
if highest_static_file_block
.filter(|highest_static_file_block| *highest_static_file_block > target)
.is_none()
{
return Err(eyre::eyre!("static files not available for target block {target}, highest is {highest_static_file_block:?}"));
}

// Move all applicable data from database to static files.
pipeline.move_to_static_files()?;
if self.offline {
info!(target: "reth::cli", "Performing an unwind for offline-only data!");
}

pipeline.unwind(target, None)?;
if let Some(highest_static_file_block) = highest_static_file_block {
info!(target: "reth::cli", ?target, ?highest_static_file_block, "Executing a pipeline unwind.");
} else {
info!(target: "reth::cli", ?target, "Executing a database unwind.");
let provider = provider_factory.provider_rw()?;
info!(target: "reth::cli", ?target, "Executing a pipeline unwind.");
}
info!(target: "reth::cli", prune_config=?config.prune, "Using prune settings");

provider
.remove_block_and_execution_above(target)
.map_err(|err| eyre::eyre!("Transaction error on unwind: {err}"))?;
// This will build an offline-only pipeline if the `offline` flag is enabled
let mut pipeline =
self.build_pipeline(config, provider_factory, components.evm_config().clone())?;

// update finalized block if needed
let last_saved_finalized_block_number = provider.last_finalized_block_number()?;
if last_saved_finalized_block_number.is_none_or(|f| f > target) {
provider.save_finalized_block_number(target)?;
}
// Move all applicable data from database to static files.
pipeline.move_to_static_files()?;

provider.commit()?;
}
pipeline.unwind(target, None)?;
Copy link
Member

@Rjected Rjected Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the reasoning behind this, that currently we pretty much always have static files and will now always be doing a pipeline unwind?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, with the work @shekhirin has been doing we always have static files, there's never a situation where static files are behind mdbx because we don't even write that data to mdbx anymore. So if static files don't have the data we can't do anything, just error out, otherwise always pipeline.

@github-project-automation github-project-automation bot moved this from Backlog to In Progress in Reth Tracker Oct 6, 2025
@mediocregopher mediocregopher requested a review from Rjected October 7, 2025 09:44
}

#[test]
fn test_write_trie_updates_sorted() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea this test is helpful to understand this pr

Copy link
Collaborator

@shekhirin shekhirin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, appreciate the cleanup in reth stage unwind

@mediocregopher mediocregopher merged commit c4e1746 into 18460-trie-changesets Oct 7, 2025
40 of 43 checks passed
@mediocregopher mediocregopher deleted the mediocregopher/18517-trie-cs-unwind branch October 7, 2025 15:59
@github-project-automation github-project-automation bot moved this from In Progress to Done in Reth Tracker Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-db Related to the database A-trie Related to Merkle Patricia Trie implementation C-enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants